﻿using _03_View_Model_MVVM_Basics.Directory.Data;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;

namespace _03_View_Model_MVVM_Basics.Directory.ViewModels
{
	public class DirectoryItemViewModel : INotifyPropertyChanged
	{
		private DirectoryItem _item;
		public event PropertyChangedEventHandler? PropertyChanged;
		private bool _isExpanded;
		public ICommand ExpandCommand;
		public ObservableCollection<DirectoryItemViewModel> Children { get; set; }

		public DirectoryItemViewModel(DirectoryItemType type, string fullPath)
		{
			_item = new DirectoryItem
			{
				Type = type,
				FullPath = fullPath
			};
			ExpandCommand = new RelayCommand(Expand);
			Children = new ObservableCollection<DirectoryItemViewModel>();
			ClearChildren();
		}

		public string FullPath
		{
			get => _item.FullPath;
			set
			{
				if (_item.FullPath == value) return;
				_item.FullPath = value;
				PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FullPath)));
			}
		}

		public DirectoryItemType Type
		{
			get => _item.Type;
			set
			{
				if (_item.Type == value) return;
				_item.Type = value;
				PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Type)));
			}
		}

		public string Name { get => Type == DirectoryItemType.Drive ? _item.Name : DirectoryStructure.GetName(FullPath); }

		public bool CanExpand { get { return Type != DirectoryItemType.File; } }

		public bool IsExpanded 
		{ 
			get => Children?.Count(f => f != null) > 0;
			set
			{
				if (value)
					Expand();
				else
					ClearChildren();
			}
		}

		public void Expand()
		{
			if (Type == DirectoryItemType.File || string.IsNullOrEmpty(FullPath)) return;
			Children.Clear();
			try
			{
				var folders = DirectoryStructure.GetDirectories(FullPath)?.Select(static fullPath => new DirectoryItemViewModel(fullPath.Type, fullPath.FullPath));
				if (folders != null)
				{
					foreach (var folder in folders)
					{
						Children.Add(folder);
					}
				}

				var files = DirectoryStructure.GetFiles(FullPath)?.Select(fullPath => new DirectoryItemViewModel(fullPath.Type, fullPath.FullPath));
				if (files != null)
				{
					foreach (var file in files)
					{
						Children.Add(file);
					}
				}
			}
			catch (Exception ex)
			{
				if (ex is UnauthorizedAccessException)
					MessageBox.Show("没有权限进入这个文件夹");
				else
					throw;
			}
		}

		public void ClearChildren()
		{
			if (Children == null)
				Children = new ObservableCollection<DirectoryItemViewModel>();
			else
				Children.Clear();
			if (Type != DirectoryItemType.File) Children.Add(null);
		}
	}
}
